import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;



public class NetworkManager {
	
	private Broadcaster broadcaster;
	private Tuner tuner;
	private MessageListener msgListener;
	private MessageSender msgSender;
	private User operatingUser;

	private static NetworkManager instance=new NetworkManager();
	
	private Hashtable<String,User> userList=new Hashtable<String,User>();
	
	private NetworkManager(){
		
	}
	
	public static NetworkManager getInstance(){
		return instance;
	}
	
	/**
	 * 1. prompt program required arguments from user
	 * 2. Store operating user information
	 * 3. Start broadcasting, tuning and listening messages
	 */
	public void initialize(){
		
		//Prompt the port to listen message, IP address and Nick Name from user
		Utility.promptParameters();
		
		
		operatingUser=new User();
		operatingUser.setAddress(Utility.getServerAddress());
		operatingUser.setPort(Utility.getServerPort());
		operatingUser.setNickName(Utility.getNickName());
		
		Utility.setBroadcastPort(443);//Set default port for broadcasting and tuning
		broadcaster=new Broadcaster(Utility.getBroadcastPort());
		tuner=new Tuner(Utility.getBroadcastPort());
		msgListener=new MessageListener(Utility.getServerPort());
		msgSender=new MessageSender();
		
		broadcaster.start();
		tuner.start();
		msgListener.start();
	}
	
	public User getOperatingUser(){
		return operatingUser;
	}
	
	public void addUser(User u){
		String key=u.getAddress()+u.getPort()+u.getNickName();
		if(!userList.containsKey(key)){			
			System.out.println(u.getNickName() + " joined at " + Calendar.getInstance().getTime().toString());
			userList.put(key,u);				
		}
	}	
	
	public Collection<User> getUsers(){
		return userList.values();
	}
	
	public User getUser(String nickName){
		User result=null;
		for(User u:userList.values()){
			if(u.getNickName().equals(nickName))
			{
				result=u;
				break;
			}
		}
		return result;
	}
	
	public void send(User recipient,String strMsg){
		msgSender.send(this.operatingUser, strMsg);//Echo own message
		msgSender.send(recipient, strMsg);
	}
	
	public void sendAll(String strMsg){
		//msgSender.send(this.operatingUser, strMsg);//Echo own message
		for(User u:userList.values()){
			msgSender.send(u,strMsg);
		}
	}
	
	
	
}
